#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <sys/types.h>
#include <sys/socket.h>
#include <jsoncpp/json/json.h>

#include "Ulit.hpp"

// #define MYSELF 1

// 给网络版本的计算器制定协议
// 规定计算式的表达式的有效载荷为： 10 + 20

namespace protocol_ns
{
#define SEP " "
#define SEP_LEN strlen(SEP)
#define HEADER_SEP "\r\n"
#define HEADER_SEP_LEN strlen(HEADER_SEP)

    int ReadStrPackage(int sockfd, std::string &inbuffer, std::string *package)
    {
        // 2.检查数据是否满足一个'7\r\n10 + 20\r\n'
        // 查找第一个HEADER_SEP出现的位置
        auto pos = inbuffer.find(HEADER_SEP);
        if (pos == std::string::npos)
            return 0;
        // 找到了第一个HEADER_SEP，这样往前的字符就表示有效载荷的长度
        std::string lenStr = inbuffer.substr(0, pos);
        int len = std::stoi(lenStr);
        int packagelen = len + lenStr.size() + HEADER_SEP_LEN * 2;
        if (inbuffer.size() < packagelen) // 判断缓冲区中是否有完整的数据
            return 0;
        // 从缓冲区中得到一条完整的数据
        *package = inbuffer.substr(0, packagelen);
        // 移除inbuffer中已经取走的数据
        inbuffer.erase(0, packagelen);
        return len; // 返回有效载荷的长度
    }

    // 报头：'7\r\n10 + 20\r\n'
    std::string RemoveHeads(const std::string &str, int len)
    {
        return str.substr(str.size() - len - HEADER_SEP_LEN, len);
    }
    std::string AddHeads(const std::string &sending_string)
    {
        std::string str;
        str = to_string(sending_string.size()) + HEADER_SEP + sending_string + HEADER_SEP;
        return str;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////
    struct Request
    {
        Request() = default;
        Request(int x, int y, char op)
            : _x(x), _y(y), _op(op)
        {
        }

        bool Deserialization(const std::string &effective_load) // 反序列化
        {
#ifdef MYSELF
            // 10 + 20
            size_t start = 0;
            std::vector<std::string> v;
            if (!Util::StringSplit(effective_load, SEP, &v))
                return false;
            if (v.size() != 3)
                return false;
            if (v[1].size() != 1)
                return false;
            _x = stoi(v[0]);
            _op = v[1][0];
            _y = stoi(v[2]);
#else
            Json::Value root;
            Json::Reader reader; // reader是用来反序列化的
            reader.parse(effective_load, root);

            _x = root["x"].asInt();
            _y = root["y"].asInt();
            _op = root["op"].asInt();

#endif
            return true;
        }

        std::string Serialization() // 序列化
        {
#ifdef MYSELF
            std::string tmp = to_string(_x) + SEP + _op + SEP + to_string(_y);
            return tmp;
#else
            Json::Value root; // Value: 一种万能对象，接受任意的kv类型
            root["x"] = _x;
            root["y"] = _y;
            root["op"] = _op;

            //Json::FastWriter wirter; // Writer：是用来进行序列化的 struct -> string
            Json::StyledWriter wirter; // Writer：是用来进行序列化的 struct -> string
            std::string tmp = wirter.write(root);
            return tmp;
#endif
        }

        void Print()const
        {
            std::cout << "x:" << _x << std::endl;
            std::cout << "y:" << _y << std::endl;
            std::cout << "op:" << _op << std::endl;
        }

    public:
        int _x;
        int _y;
        char _op;
    };

    struct Response
    {
        Response(int result = 0, int code = 0)
            : _result(result), _code(code)
        {
        }

        std::string Serialization()
        {
#ifdef MYSELF
            // 手动序列化
            std::string tmp = to_string(_result) + SEP + to_string(_code);
#else
            Json::Value root; // Value: 一种万能对象，接受任意的kv类型
            root["result"] = _result;
            root["code"] = _code;
            Json::StyledWriter writer;
            std::string tmp = writer.write(root);
#endif
            return tmp;
        }

        bool Deserialization(const std::string &effective_load)
        {

#ifdef MYSELF
            // 手动反序列化
            //  30 0
            std::vector<std::string> v;
            if (!Util::StringSplit(effective_load, SEP, &v))
                return false;
            if (v.size() != 2)
                return false;
            _result = stoi(v[0]);
            _code = stoi(v[1]);
            return true;
#else
            Json::Value root;
            Json::Reader reader;
            reader.parse(effective_load,root);
            _result=root["result"].asInt();
            _code=root["code"].asInt();
#endif
        }

        int _result;
        int _code;
    };
}
